from typing import Dict, Any, Optional
from fastapi import HTTPException, status

class DifyAPIError(Exception):
    """
    Dify API 错误
    
    用于封装来自 Dify API 的错误响应
    """
    def __init__(
        self, 
        detail: str = "API请求失败", 
        status_code: int = 500, 
        error_data: Optional[Dict[str, Any]] = None
    ):
        """
        初始化 Dify API 错误
        
        Args:
            detail: 错误详情
            status_code: HTTP状态码
            error_data: 错误数据
        """
        # 确保detail不为空
        self.detail = detail or "API请求失败(无详细信息)"
        self.status_code = status_code
        self.error_data = error_data or {}
        super().__init__(self.detail)
        
    def __str__(self) -> str:
        """返回错误字符串表示"""
        if self.detail:
            return self.detail
        elif self.error_data:
            return f"API错误: {self.error_data}"
        else:
            return f"API错误(状态码:{self.status_code})"

class InvalidRequestError(HTTPException):
    """
    无效请求错误
    
    用于处理请求参数验证失败的情况
    """
    def __init__(
        self,
        detail: str = "请求参数无效",
        error_data: Optional[Dict[str, Any]] = None
    ):
        super().__init__(
            status_code=status.HTTP_400_BAD_REQUEST,
            detail=detail
        )
        self.error_data = error_data or {}

class AuthenticationError(HTTPException):
    """
    认证错误
    
    用于处理API认证失败的情况
    """
    def __init__(
        self,
        detail: str = "认证失败，请检查API密钥"
    ):
        super().__init__(
            status_code=status.HTTP_401_UNAUTHORIZED,
            detail=detail
        )

class FileUploadError(HTTPException):
    """
    文件上传错误
    
    用于处理文件上传失败的情况
    """
    def __init__(
        self,
        detail: str = "文件上传失败",
        error_code: Optional[str] = "file_upload_error",
        status_code: int = status.HTTP_500_INTERNAL_SERVER_ERROR,
        error_data: Optional[Dict[str, Any]] = None
    ):
        super().__init__(
            status_code=status_code,
            detail=detail
        )
        self.error_code = error_code
        self.error_data = error_data or {}

# 标准错误响应格式
def get_error_response(exception: HTTPException) -> Dict[str, Any]:
    """生成标准的错误响应格式"""
    response = {
        "status": "error",
        "message": exception.detail,
        "code": getattr(exception, "error_code", None)
    }
    
    # 添加额外错误数据（如果有）
    if hasattr(exception, "error_data") and exception.error_data:
        response["data"] = exception.error_data
        
    return response
